package com.yps.io.bio;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author yps
 * BIO服务端 
 * 	服务端提供IP和监听端口，客户端通过连接操作想服务端
 * 监听的地址发起连接请求，通过三次握手连接，如果连接成功
 * 建立，双方就可以通过套接字进行通信。
 	传统的同步阻塞模型开发中，ServerSocket负责绑定
 * IP地址，启动监听端口；Socket负责发起连接操作。连接
 * 成功后，双方通过输入和输出流进行同步阻塞式通信。 
 	简单的描述一下BIO的服务端通信模型：
 	采用BIO通信模型的服务端，通常由一个独立的Acceptor线程
 	负责监听客户端的连接，它接收到客户端连接请求之后为每个客户端
 	创建一个新的线程进行链路处理没处理完成后，
 	通过输出流返回应答给客户端，线程销毁。即典型的一请求一应答通宵模型。
 	缺点：
 	缺乏弹性伸缩能力，当客户端并发访问量增加后，服务端的线程个数和客户端并
 	发访问数呈1:1的正比关系，Java中的线程也是比较宝贵的系统资源，线程数量快速膨胀后，
 	系统的性能将急剧下降，随着访问量的继续增大，系统最终就死-掉-了。
 */
public final class ServerNormal {
	//默认的端口号
	private static int DEFALUT_PROT = 12344;
	//单例的ServerSocket 
	private static ServerSocket server;
	//根据传入参数调用监听端口，如果没就调用默认方法
	public static void start() throws IOException{
		start(DEFALUT_PROT);
	}
	
	private synchronized static void start(int port) throws IOException {
		if(server != null) 
			return ;
		try {
			//通过构造函数穿件ServerSocket
			//如果端口合法和空闲，服务端监听成功
			server = new ServerSocket(port);
			System.out.println("服务端已经启用，端口号："+port);
			server.setSoTimeout(3000);
			//通过无限玄幻监听客户端口
			//如果没有客户端结果.将阻塞在accept上
			while(true){
				Socket socker = server.accept();//这里会监听端口，端口有请求才会往下走，否则阻塞
				//当有新的客户端请求接入时候，会执行下面的代码
				//创建一个新的线程处理这个socket链路
				new Thread(new BioServerhandler(socker)).start();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//清理内容
			if(server !=null){
				System.out.println("服务端已经关闭");
				server.close();
				server = null;//切掉对象
			}
		}
	}
	
	
}
